/**
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package br.biofoco.p2p.peer;

import java.io.IOException;
import java.util.Random;

import org.codehaus.jackson.JsonParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import br.biofoco.p2p.bootstrap.PeerApp;
import br.biofoco.p2p.config.PeerConfigurationException;
import br.biofoco.p2p.config.PeerNodeConfigurator;
import br.biofoco.p2p.rpc.TransportManager;
import br.biofoco.p2p.rpc.rest.PeerHandler;

import com.google.common.base.Preconditions;
import com.google.inject.Inject;

public class PeerNodeFactory {

	private static final Logger LOGGER = LoggerFactory.getLogger(PeerApp.class);
	private static final Random RANDOM = new Random(System.nanoTime());

	private final PeerNodeConfigurator peerConfigurator;
	private final TransportManager manager;	
	private PeerConfig config;
	private DhtFactory dhtFactory;

	@Inject
	public PeerNodeFactory(PeerNodeConfigurator peerConfigurator, TransportManager manager, DhtFactory dhtFactory) {
		this.peerConfigurator = peerConfigurator;
		this.manager = manager;
		this.dhtFactory = dhtFactory;
	}
	

	public PeerNode createPeerNode(PeerConfig config) throws PeerConfigurationException {

		Preconditions.checkNotNull(config);

		if (config.getPeerID() == null) {
			LOGGER.debug("creating a peerID");
			ID id = createRandomPeerID();
			config.setPeerID(id);
		}
		
		return new PeerNodeImpl(config, manager, dhtFactory);
	}

	private ID createRandomPeerID() {
		String input = "" + RANDOM.nextLong() + System.nanoTime();
		return IDFactory.newID(input.getBytes());
	}

	public PeerNode getPeerInstance(boolean create, boolean persist) throws JsonParseException, PeerConfigurationException, IOException {
		
		config = peerConfigurator.getConfig();
		PeerNode peerNode = null;

		if (create) {
			peerNode = createPeerNode(config);
			
			LOGGER.debug("PeerNode=" + peerNode.getPeerID());

			PeerHandler.setPeer(peerNode); // TODO it's just for RestTransport			
		}

		if (persist) saveConfigIfAbsent(config);

		return peerNode;
	}

	private void saveConfigIfAbsent(PeerConfig config) throws PeerConfigurationException, IOException {
		if (config.getPeerID() == null) {
			LOGGER.debug("Saving a new config file with PeerID generated!");
			peerConfigurator.savePeerConfig(config);
		}

	}
}
